import java.util.ArrayList;
import java.util.Collections;

/**
 * @authors Thibault Fontaine, Pierre Duchemin
 * 
 */
public class Diagramme{

	private ArrayList<Tache> liste;
	private String nom;
	private Tache debut, fin;

	public Diagramme(String nom) {
		assert (nom != null);

		this.nom = nom;
		this.liste = new ArrayList<Tache>();

		this.debut = new Tache('X', 0, "DEBUT");
		this.debut.setDateDebutPlusTard(0);
		this.debut.setDateDebutPlusTot(0);

		this.fin = new Tache('Y', 0, "FIN");

		this.liste.add(this.debut);
		this.liste.add(this.fin);
	}
	
	public void sort() {
		Collections.sort(this.liste);
		this.liste.add(0, this.liste.remove(this.liste.size()-2)); //replacement de X-DEBUT au debut
	}

	public Tache getTacheParCode(char code) {
		assert (code >= 65 && code <= 90);

		Tache retour = null;

		for (Tache t : this.liste) {
			if (t.getCode() == code) {
				retour = t;
			}
		}

		return retour;
	}

	public Tache getTacheParId(int id) {
		assert (id > 0);

		Tache retour = null;

		for (Tache t : liste) {
			if (t.getNumTache() == id) {
				retour = t;
			}
		}

		return retour;
	}

	public void ajTache(Tache t) {
		assert (t != null);

		this.liste.add(this.liste.size() - 1, t);
		t.ajTachePrec(this.debut);
		this.fin.ajTachePrec(t);
	}

	public void ajTachePrec(Tache tacheCour, Tache tachePrec) {
		assert (tacheCour != null);
		assert (tachePrec != null);

		if (!tacheCour.equals(tachePrec)) {

			tacheCour.ajTachePrec(tachePrec);

			this.debut.supprTacheSuiv(tacheCour);
			tacheCour.supprTachePrec(this.debut);

			this.fin.supprTachePrec(tachePrec);
			tachePrec.supprTacheSuiv(this.fin);
		}
	}

	public void calculDatePlusTot() {
		float tpsMax;

		// Parours de la liste des taches
		for (int i = 1; i < this.liste.size(); i++) {
			Tache tacheCour = this.liste.get(i);

			tpsMax = 0;
			// Parcours de la liste des taches precedant directement la tache actuelle
			for (int j = 0; j < tacheCour.getPrec().size(); j++) {

				Tache tachePrec = tacheCour.getPrec().get(j);

				// verification si les dates existent dans les taches de l'arraylist des taches precedentes
				if (tachePrec.getDateDebutPlusTot() + tachePrec.getDuree() > tpsMax) {

					tpsMax = tachePrec.getDateDebutPlusTot() + tachePrec.getDuree();
				}
			}

			tacheCour.setDateDebutPlusTot(tpsMax);
		}

		// Applique a FIN : ddpTard = ddpTot
		this.fin.setDateDebutPlusTard(this.fin.getDateDebutPlusTot());
	}

	public void calculDatePlusTard() {
		float tpsMin;

		for (int i = this.liste.size() - 2; i >= 1; i--) {
			Tache tacheCour = this.liste.get(i);

			// Parcours de la liste des taches precedant directement la tache actuelle
			tpsMin = this.fin.getDateDebutPlusTard();
			for (int j = 0; j < tacheCour.getSuiv().size(); j++) {

				// Verification si les dates existent dans les taches de l'arraylist des taches suivantes
				Tache tacheSuiv = tacheCour.getSuiv().get(j);

				if (tacheSuiv.getDateDebutPlusTard() - tacheCour.getDuree() < tpsMin) {
					tpsMin = tacheSuiv.getDateDebutPlusTard() - tacheCour.getDuree();
				}
			}

			tacheCour.setDateDebutPlusTard(tpsMin);
		}
	}

	public String toString() {
		String s = this.nom + "\n";

		for (Tache t : this.liste) {
			s += t.toString() + "\n";
		}

		s += "Chemin critique : ";
		for (int i = 1; i < this.liste.size() - 1; i++) {
			Tache tachCour = this.liste.get(i);
			s += (tachCour.getDateDebutPlusTard() == tachCour.getDateDebutPlusTot()) ? tachCour.getCode() + " " : "";
		}

		return s += "\n";
	}

	public ArrayList<Tache> getListe() {
		return this.liste;
	}
}